
use crate::physical_plan::window::window_group::WindowGroup;
use crate::physical_plan::window::{WindowElement, WindowIndex};
use std::cmp::Ordering;
use crate::data_frame::single_data::SingleData;
use crate::data_frame::value::{ElementValue, RealValue};
use std::vec::IntoIter;
use std::slice::{Iter, IterMut};

/*
    对DataInstance进行窗口处理的索引结构体
*/
#[derive(Clone)]
pub struct WindowElementDataInstance{
    sequential: u64,
    uniqueness: u64,
    data: SingleData,
}

impl WindowElement<ElementValue,RealValue> for WindowElementDataInstance{
    type MapValue = SingleData;
    fn index(&self)->WindowIndex{
        WindowIndex::new_seque_unique(self.sequential, self.uniqueness)
    }
    fn index_to_value(&self)->Self::MapValue{
        self.data.clone()
    }
    fn index_value_ref(&self)->&Self::MapValue{
        &self.data
    }
    fn index_value_mut(&mut self)->&mut Self::MapValue{
        &mut self.data
    }
}
impl Eq for WindowElementDataInstance{}
impl PartialEq for WindowElementDataInstance{
    fn eq(&self, other: &Self) -> bool{
        if self.sequential == other.sequential && self.uniqueness == other.uniqueness{
            true
        }else{
            false
        }
    }
}
impl Ord for WindowElementDataInstance{
    fn cmp(&self, other: &Self) -> Ordering{
        return self.index().cmp(&other.index());
    }
}
impl PartialOrd for WindowElementDataInstance{
    fn partial_cmp(&self, other: &Self) -> Option<Ordering>{
        return self.index().partial_cmp(&other.index());
    }
}
impl WindowElementDataInstance{
    pub fn new(sequential: u64, uniqueness: u64, data: SingleData)->WindowElementDataInstance{
        WindowElementDataInstance{
            sequential: sequential,
            uniqueness: uniqueness,
            data: data,
        }
    }
    pub fn data_mut(&mut self)->&mut SingleData{
        &mut self.data
    }
}

#[derive(Clone)]
pub struct GroupData{
    pub data: WindowGroup<ElementValue, RealValue, WindowElementDataInstance>,
}

impl IntoIterator for GroupData{
    type Item = WindowElementDataInstance;
    type IntoIter = IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter{
        self.data.into_iter()
    }
}

impl GroupData{
    pub fn new()->Self{
        GroupData{
            data: WindowGroup::new(),
        }
    }
    pub fn push(&mut self, element: WindowElementDataInstance){
        self.data.push(element);
    }
    pub fn new_with_window_group(window_group: WindowGroup<ElementValue, RealValue, WindowElementDataInstance>) ->Self{
        GroupData{
            data: window_group
        }
    }
    pub fn len(&self)->usize{
        self.data.element_list.len()
    }
    pub fn iter_mut(&mut self)->IterMut<'_,WindowElementDataInstance>{
        self.data.element_list.iter_mut()
    }
    pub fn iter(&self)->Iter<'_,WindowElementDataInstance>{
        self.data.element_list.iter()
    }
}